package net.bat.advice;

import java.util.Map;

import net.bat.dao.UserDAO;
import net.bat.dao.UserDAO.Action;
import net.bat.entity.IdEntity;
import net.bat.service.account.ShiroDbRealm.ShiroUser;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogAspect {
	static protected Logger log = LoggerFactory.getLogger(LogAspect.class);
	@Autowired
	private UserDAO dao;

	@AfterReturning(value = "execution(* net.bat.dao.UserDAO.update(..)) && args( entity_name,id, rmap)", returning = "result")
	public void afterUpdate(JoinPoint point, Object result, String entity_name, Long id, Map<String, Object> rmap)
			throws Exception {
		// 为空时调用add
		if ((id != null) && (id > 0)) {
			logOper(entity_name, id, rmap, Action.UPDATE);
		} else {
			logOper(entity_name, ((IdEntity) result).getId(), rmap, Action.ADD);
		}
	}

	@AfterReturning(value = "execution(* net.bat.dao.UserDAO.add(..)) && args( entity_name, rmap)", returning = "result")
	public void afterAdd(JoinPoint point, Object result, String entity_name, Map<String, Object> rmap) throws Exception {
		logOper(entity_name, ((IdEntity) result).getId(), rmap, Action.ADD);
	}

	@After("execution(* net.bat.dao.UserDAO.remove(..)) && args( entity_name, ids)")
	public void afterRemove(JoinPoint point, String entity_name, Object[] ids) throws Exception {
		for (Object id : ids) {
			logOper(entity_name, id, null, Action.REMOVE);
		}
	}

	static public <T extends IdEntity> void logOper(String entity_name, Object id, Map<String, Object> rmap, Action op)
			throws Exception {
		Subject subject = SecurityUtils.getSubject();
		ShiroUser uinf = (ShiroUser) subject.getPrincipal();
		// user ip 可以从shiro拿到
		String fld_desc = "";
		if (rmap != null) {
			fld_desc = rmap.toString();
		}
		// 如果日志写入数据库，日志写操作是可以和之前的业务操作在一个事务中回滚的
		log.info("[{}]_{} :{}", entity_name + "@" + id, op, fld_desc);
	}

}
